from rest_framework import generics, permissions
from audit.models import AuditManagement
from lib.rest_api.perms import HasDjangoPermission
from rest_framework import serializers
from django.shortcuts import reverse
from .. import models
from django.db import models as djangoModels

class ProjectCanViewPermission(permissions.BasePermission):
    """
    To use this permission class, override `get_permissions()` method in your view
    class.
    """
    def __init__(self, project_id):
        self.project = models.Project.objects.select_related('creator').get(id=project_id)

    def has_permission(self, request, view):
        return self.project.can_view(request.user)


class ProjectSubListView(generics.ListAPIView):
    """
    User needs to set `queryset` class attribute.
    """
    def get_permissions(self):
         project_id = self.kwargs.get('project_pk')
         return [
             permissions.OR(
                 ProjectCanViewPermission(project_id),
                 HasDjangoPermission(["user.can_manage_projects"])
             )
         ]
 
    def get_queryset(self):
        project_pk = self.kwargs.get('project_pk')
        return (
            self.queryset.filter(project__id=project_pk)
        )

    
class ProjectSubWithAuditListView(ProjectSubListView):
    def get_queryset(self):
        project_pk = self.kwargs.get('project_pk')
        return (
            self.queryset.filter(project__id=project_pk)
            .prefetch_related(
                djangoModels.Prefetch(
                    'audit_management',
                    queryset=AuditManagement.objects.order_by('-updated_at'),
                    to_attr='_audit_management'
                )
            )
        )


class ProjectSubSerializer(serializers.ModelSerializer):
    link = serializers.SerializerMethodField()
    
    def get_link(self, obj: djangoModels.Model):
        return obj.get_link(obj.project.id, obj.id)


class ProjectSubWithAuditSerializer(ProjectSubSerializer):
    audit_status = serializers.SerializerMethodField()
    
    def get_audit_status(self, obj: djangoModels.Model):
        ams = getattr(obj, '_audit_management', [])
        return ams[0].status if ams else None



